package cn.gov.cbrc.core.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import cn.gov.cbrc.core.excp.BaseException;
import cn.gov.cbrc.core.util.PropertiesUtil;
import cn.gov.cbrc.east.verify.S_Table;

@SuppressWarnings("unused")
public class DataSourceUtil {
	private static final Logger logger = LogManager.getLogger(DataSourceUtil.class);
	private static Context ctx;
	private static Map<String, DataSource> tds = new HashMap<String, DataSource>();

	static {
		try {
			ctx = new InitialContext();
		}
		catch (NamingException e) {
			logger.error("Init context failure :" + e);
		}
	}

	/**
	 * <p>方法描述: 获取数据源</p> <p>方法备注: </p>
	 * 
	 * @param jndiName
	 * @return <p>创建人：王川</p> <p>创建时间：Jun 10, 2014 9:13:08 AM</p>
	 */
	public static DataSource getDataSource(String jndiName) {
		DataSource ds = tds.get(jndiName);
		if (ds == null) {
			try {
				if(PropertiesUtil.getProperty("sys.datasource", false)){
					ds = (DataSource) ctx.lookup(jndiName);
				}
				else
					ds = getDataSourceFromConfig(jndiName);
				if (ds != null)
					tds.put(jndiName, ds);
				return ds;
			}
			catch (Exception e) {
				logger.error("Datasource <" + jndiName + "> was  not find :" + e);
				return null;
			}
		}
		return ds;
	}

	public static DataSource getDataSourceFromConfig(String jndiName) {
		BasicDataSource bds = null;
		try {
			bds = new BasicDataSource();
			bds.setDriverClassName(PropertiesUtil.getProperty("jdbc.driverClassName"));
			bds.setInitialSize(PropertiesUtil.getProperty("jdbc.initialSize", 5));
			bds.setMaxActive(PropertiesUtil.getProperty("jdbc.maxActive", 100));
			bds.setMaxIdle(PropertiesUtil.getProperty("jdbc.maxIdle", 30));
			bds.setMinIdle(PropertiesUtil.getProperty("jdbc.minIdle", 3));
			bds.setMaxWait(PropertiesUtil.getProperty("jdbc.maxWait", 10000));
			bds.setUrl(PropertiesUtil.getProperty(jndiName+".jdbc.url"));
			//bds.setUsername(PropertiesUtil.getProperty(jndiName+".jdbc.username"));
			//bds.setPassword(PropertiesUtil.getProperty(jndiName+".jdbc.password"));
			testDataSource(bds);
			tds.put(jndiName, bds);
		}
		catch (Exception e) {
			logger.error("Datasource <" + jndiName + "> can't create:" + e);
			return null;
		}
		return bds;
	}

	/**
	 * 判断该数据源是否能够获得有效连接
	 * 
	 * @param ds 数据源
	 * @return boolean
	 * @throws BaseException
	 */
	public static boolean testDataSource(DataSource ds) throws BaseException {
		if (ds == null)
			return false;
		boolean flag = false;
		Connection conn = null;
		try {
			conn = ds.getConnection();
		}
		catch (SQLException e) {
			//releaseDataSource(ds);
			logger.error(ds + "#testDataSource():" + "数据源创建失败!");
			throw new BaseException(e);
		}
		finally {
			if (conn != null) {
				try {
					flag = true;
					conn.close();
				}
				catch (SQLException e) {
					logger.error(ds + "关闭连接失败！" + e);
				}
			}
		}
		return flag;
	}

	/**
	 * <p>方法描述: 释放数据源</p>
	 * <p>方法备注: </p>
	 * @param ds
	 * @throws BaseException
	 * <p>创建人：王川</p>
	 * <p>创建时间：Jul 22, 2015 3:42:53 PM</p>
	 *
	 */
	public static void releaseDataSource(DataSource ds) throws BaseException {

		if (ds != null) {
			if (ds instanceof BasicDataSource) {
				BasicDataSource bds = (BasicDataSource) ds;
				try {
					bds.close();
				}
				catch (SQLException e) {
					logger.error(e);
					throw new BaseException(e);
				}
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		
		//while (true) {
			Thread t = new Thread(){
				@Override
				public void run() {
					try {
						Connection conn = DBUtil.getConnection("check");
						String sql = "select * from S_Table;";
						List<S_Table> list = QueryRunnerUtil.getInstance().query(conn, sql, new BeanListHandler<S_Table>(S_Table.class));
						Statement st = conn.createStatement();
						for(S_Table s:list){
							System.out.println(s.get_tableName());
						}
						DBUtil.closeConnection("check");
					}
					catch (Exception e) {
						System.out.println(e);
					}
				}
			};
			t.start();
			Thread.sleep(100);
		//}
		
	}

}
